package standardize;

import parser.CodeReviewToken;
import parser.JavaTokenTypes;

import java.util.ArrayList;

/**
 * @author begge
 * @license http://www.freebsd.org/copyright/license.html  BSD License (4 Clause)
 * Date: May 25, 2007
 */
public class NaturalForm {
    int bracket;
    int paren;
    int equality;
    int curly;
    private final ArrayList<CodeReviewToken> tokens;
    private final CodeReviewToken first;

    public NaturalForm(ArrayList<CodeReviewToken> tokens, final CodeReviewToken first) {
        this.tokens = tokens;
        this.first = first;
    }

    //for some reason, in the AST remove some keyword such as "while" in do while
    public CodeReviewToken autoCompleteHead() {

        int i = first.getId() - 1;
        for (; i >= 0; i--) {
            String tokenText = tokens.get(i).getText();
            if (tokenText.equals("(")
                    || tokenText.equals("[")
                    || tokenText.equals("<")
                    || tokenText.equals("{")
                    || tokenText.equals("while")
                    || tokenText.equals("try")
                    || tokenText.equals("finally")
                    || tokenText.equals("do")
                    ) {
                continue;
            }
            break;
        }

        return i > 0 ? tokens.get(i + 1) : tokens.get(0);
//        return start;
    }

    //we use the statements in AST that removes ], ), { } ....
    //so that need function to complete a natural form
    public CodeReviewToken autoCompleteTail(CodeReviewToken last) {

        sum(last);
        int i;
        for (i = last.getId() + 1; i < tokens.size() &&
                (bracket > 0 || paren > 0 || equality > 0 || curly > 0)
                ; i++) {
            CodeReviewToken token = tokens.get(i);
            if (addToken(token)) {
                continue;
            }
            if (token.getType() == JavaTokenTypes.SEMI) {
                continue;
            }
            break;
        }

        return i > 0 ? tokens.get(i - 1) : tokens.get(0);
    }

    /*
     * Add up the number of mismatched tokens between the start and proposed last token.
     */
    private void sum(final CodeReviewToken last) {
        for (int i = autoCompleteHead().getId(); i < last.getId(); i++) {
            addToken(tokens.get(i));
        }
        bracket = bracket < 0 ? 0 : bracket;
        paren = paren < 0 ? 0 : paren;
        equality = equality < 0 ? 0 : equality;
        curly = curly < 0 ? 0 : curly;
    }

    private boolean addToken(CodeReviewToken token) {
        switch (token.getText().charAt(0)) {
            case'[':
                bracket++;
                return true;
            case']':
                bracket--;
                return true;
            case'{':
                curly++;
                return true;
            case'}':
                curly--;
                return true;
            case'<':
                equality++;
                return true;
            case'>':
                equality--;
                return true;
            case'(':
                paren++;
                return true;
            case')':
                paren--;
                return true;
            default:
                return false;
        }
    }
}
